package com.apache.portal.service.plugin;

import com.apache.api.vo.ResultEntity;
import com.apache.client.UctCoreClient;
import com.apache.client.UctProtoclClient;
import com.apache.portal.common.PortalPlugin;
import com.apache.portal.common.annotion.AnntationBean;
import com.apache.portal.common.enums.FusMethodEnum;
import com.apache.portal.common.util.PortalPubFactory;
import com.apache.rpc.common.LoadRpcService;
import com.apache.rpc.entity.InterfaceRegister;
import com.apache.tools.MD5Utils;
import com.apache.tools.NumberUtils;
import com.apache.tools.StrUtil;
import com.apache.uct.common.LoginUser;
import com.apache.uct.common.ToolsUtil;
import com.apache.uct.common.entity.User;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * @author xhe
 * 对接funds钱包对接插件
 */
@AnntationBean(name = "fus")
public class FusSystemPluginImpl implements PortalPlugin {

    private Logger log = LoggerFactory.getLogger(FusSystemPluginImpl.class);

    /* (non-Javadoc)
     * @see com.apache.portal.plugin.PortalPlugin#doInvoke(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.util.Map)
     */
    public Object doInvoke(HttpServletRequest request, HttpServletResponse response,
            Map<String, String> params) {
        String doCode = params.get("doCode");
        LoginUser loginUser = PortalPubFactory.getInstance().getLoginUser(request);
        Map<String, Object> paramsMap = new HashMap<String, Object>();
        paramsMap.putAll(params);
        ResultEntity entity = new ResultEntity();
        entity.setResult("false");

        //settleAccountNo不传就是当前登录人
        String accountNo = getAccountNo(request, String.valueOf(paramsMap.get("settleAccountNo")));
        switch (FusMethodEnum.getName(doCode)) {
        case F001://查询开户信息
            String userId = loginUser.getUserId();
            paramsMap.put("userId", userId);
            paramsMap = toMapDelNull(paramsMap);
            entity = (ResultEntity) LoadRpcService.service()
                    .doServiceClient("fundsService", "fundsMyAccountByUserId", paramsMap,
                            getInterfaceRegister());
            //			log.info("开户检测结果返回：" + entity.getMessage());
            break;
        case F002://开户
            String accountNewNo = getAccountCreateNo();
            paramsMap.put("userId", loginUser.getUserId());
            paramsMap.put("userEname", accountNewNo);
            paramsMap.put("createUser", loginUser.getUserEname());
            paramsMap.put("createUserName", loginUser.getUserCname());
            String fundPas = String.valueOf(paramsMap.get("fundPas"));
            if (StrUtil.isNull(fundPas)) {
                entity.setMessage("口令不能为空");
                break;
            }
            //paramsMap.put("password", MD5Utils.crypt(fundPas));
            paramsMap.put("password", fundPas);
            paramsMap = toMapDelNull(paramsMap);
            log.info("开通资金账号，请求参数：paramsMap=" + paramsMap);
            //调用RPC
            entity = (ResultEntity) LoadRpcService.service()
                    .doServiceClient("fundsService", "fundsOpenAccount", paramsMap,
                            getInterfaceRegister());
            log.info("处理结果返回：" + entity.getMessage());
            if ("true".equals(entity.getResult()) && null != entity.getEntity() && !"false"
                    .equals(entity.getEntity().toString())) {
                //				request.getSession().setAttribute("openFunds", "T");//标记已经开通钱包功能
                //				request.getSession().setAttribute("loginFus", "T");//标记已经登录

                //修改user表
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("userEname", loginUser.getUserEname());
                String cardType = "1";
                String cardNum = accountNewNo;
                map.put("cardType", cardType);//卡号类别:1虚拟钱包，2银行卡
                map.put("cardNum", cardNum);//卡号
                ResultEntity entity22 = UctCoreClient.editUserInfo(map);
                //下面这段放开注释，可能冲抵了之前补充的userCname值（首次注册，完善信息，开通钱包后 add xhe 2016-07-13 00:51）
                if (("true".equals(entity22.getResult())) && !ToolsUtil
                        .isEmpty(entity22.getEntity())) {
                    LoginUser loginUserReq = (LoginUser) request.getSession()
                            .getAttribute("loginUser");
                    User user = loginUser.getUser();
                    user.setCardType(cardType);
                    user.setCardNum(cardNum);
                    loginUserReq.setUser(user);
                    request.getSession().setAttribute("loginUser", loginUserReq);

                }
                entity.setResult("true");
                entity.setMessage("开通成功");
                entity.setEntity(entity.getEntity());
            } else {
                entity.setMessage("开通失败");
            }
            break;
        case F003://查询开户信息
            paramsMap.put("userEname", accountNo);
            paramsMap = toMapDelNull(paramsMap);
            //调用RPC
            entity = (ResultEntity) LoadRpcService.service()
                    .doServiceClient("fundsService", "fundsMyAccount", paramsMap,
                            getInterfaceRegister());
            log.info("处理结果返回：" + entity.getMessage());
            break;
        case F004://查询余额
            log.info("查询账户余额：" + accountNo);
            paramsMap.put("userEname", accountNo);
            paramsMap = toMapDelNull(paramsMap);
            entity = (ResultEntity) LoadRpcService.service()
                    .doServiceClient("fundsService", "fundsMyCache", paramsMap,
                            getInterfaceRegister());
            //判断结果
            log.info("处理结果返回：" + JSONObject.fromObject(entity).toString());
            break;
        case F005://充值转账操作等
            String amount = String.valueOf(paramsMap.get("amount"));
            String direction = String.valueOf(paramsMap.get("direction"));
            if (StrUtil.isNull(accountNo) && StrUtil.isNull(amount) && StrUtil.isNull(direction)) {
                entity.setMessage("参数不能为空");
                break;
            }
            try {
                Double.parseDouble(amount);
            } catch (NumberFormatException e) {
                entity.setMessage("输入操作数量格式不对");
                break;
            }
            //执行
            double amountL = NumberUtils.getDouble(amount, 0, false);
            long amounLong = Math.round(NumberUtils.multiply(amountL, 100, 2));
            entity = sendFunds(accountNo, direction, String.valueOf(amounLong));
            log.info("处理结果返回：" + entity.getMessage());
            //			//判断结果
            //			if (entity != null) {
            //				if ("true".equals(entity.getResult())  && "true".equals(entity.getEntity())) {
            //					entity.setResult("true");
            //					entity.setMessage("操作成功");
            //				} else {
            //					String msgStr = entity.getMessage().toString();
            //					if (msgStr.indexOf("F005") > -1) {
            //						msg = new ResultMsg("T", "您当前可操作余额不足！");
            //					} else {
            //						msg = new ResultMsg("T", "操作失败，请稍后！");
            //					}
            //				}
            //			}
            break;
        case F006://资金变化流水查询
            //封装参数
            String pageSize = params.get("pageSize");
            String pageIndex = params.get("pageIndex");
            pageSize = StrUtil.doNull(pageSize, params.get("rows"));
            pageIndex = StrUtil.doNull(pageIndex, params.get("page"));

            paramsMap.put("pageSize", StrUtil.doNull(pageSize, "10"));
            paramsMap.put("pageIndex", StrUtil.doNull(pageIndex, "1"));
            if ("manager".equals(params.get("source"))) {
                //管理人员人员查询 accountNo 可以为空
            } else {
                //会员自己查询，不能尾款
                if (StrUtil.isNull(accountNo)) {
                    break;
                }
            }
            paramsMap.put("userId", accountNo);
            String actype = String.valueOf(params.get("actype"));
            if (StrUtil.isNotNull(actype)) {
                paramsMap.put("actype", getSqlInStr(actype));
            }
            //			BaseOsCache oscache = OsCacheOtherManager.getInstance().getBaseOsCache("fus_my_data_", 60);
            //			String cacheKey = oscache.getCacheKey(doCode, params);
            //			entity = (ResultEntity) oscache.get(cacheKey);
            //			if (ToolsUtil.isEmpty(entity)) {
            //获取结果
            //				System.out.println(accountNo);
            entity = (ResultEntity) LoadRpcService.service()
                    .doServiceClient("fundsService", "fundsFlowing", paramsMap,
                            getInterfaceRegister());
            //				if (!ToolsUtil.isEmpty(entity.getEntity())) {
            //					oscache.put(cacheKey, entity);
            //				}
            //			}
            break;
        case F007://设置口令密码
            String passold = String.valueOf(paramsMap.get("passold"));
            String passnew = String.valueOf(paramsMap.get("passnew"));
            if (StrUtil.isNull(passold) && StrUtil.isNull(passnew)) {
                entity.setMessage("口令不能为空");
                break;
            }
            paramsMap.put("userEname", accountNo);
            try {
                paramsMap.put("passold", MD5Utils.crypt(passold));
                paramsMap.put("passnew", MD5Utils.crypt(passnew));
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }

            //调用RPC
            entity = (ResultEntity) LoadRpcService.service()
                    .doServiceClient("fundsService", "fundsAccountPass", paramsMap,
                            getInterfaceRegister());
            //
            //			//判断结果
            //			if (entity2 != null) {
            //				if ("true".equals(entity2.getResult()) && entity2.getEntity() != null
            //						&& "true".equals(entity2.getEntity())) {
            //					msg = new ResultMsg("T", "操作成功");
            //				} else {
            //					String msgStr = entity2.getMessage().toString();
            //					//					System.out.println(msgStr);
            //					if (msgStr.indexOf("F011") > -1 || msgStr.indexOf("F004") > -1) {
            //						msg = new ResultMsg("F", "账号或旧口令输入有误");
            //					} else {
            //						msg = new ResultMsg("F", "操作失败");
            //					}
            //				}
            //			}
            break;
        case F008://口令校验
            String pass = String.valueOf(paramsMap.get("pass"));
            if (StrUtil.isNull(pass)) {
                entity.setMessage("口令不能为空");
                break;
            }
            paramsMap.put("userEname", accountNo);
            try {
                paramsMap.put("password", MD5Utils.crypt(pass));
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }

            //调用RPC
            entity = (ResultEntity) LoadRpcService.service()
                    .doServiceClient("fundsService", "fundsAccountLogin", paramsMap,
                            getInterfaceRegister());
            //
            //			//判断结果
            //			if (entity3 != null) {
            //				if ("true".equals(entity3.getResult()) && entity3.getEntity() != null
            //						&& "true".equals(entity3.getEntity())) {
            //					msg = new ResultMsg("T", "操作成功");
            //					//后续保存资金账号信息
            //					request.getSession().setAttribute("loginFus", "T");
            //				} else {
            //					String msgStr = entity3.getMessage().toString();
            //					//					System.out.println(msgStr);
            //					if (msgStr.indexOf("F011") > -1 || msgStr.indexOf("F004") > -1) {
            //						msg = new ResultMsg("F", "资金账户口令有误");
            //					} else {
            //						msg = new ResultMsg("F", "操作失败");
            //					}
            //				}
            //			}
            break;
        case F009://F009:账户列表查询
            paramsMap.put("pageSize", StrUtil.doNull(params.get("rows"), "10"));
            paramsMap.put("pageIndex", StrUtil.doNull(String.valueOf(params.get("page")), "1"));
            paramsMap = toMapDelNull(paramsMap);
            entity = (ResultEntity) LoadRpcService.service()
                    .doServiceClient("fundsService", "fundsUserList", paramsMap,
                            getInterfaceRegister());
            break;
        case F010://F010:给指定账户开户操作
            String userEname = String.valueOf(paramsMap.get("userEname"));
            String userSettleNewAccountNo = String.valueOf(paramsMap.get("settleAccountNo"));
            paramsMap.put("userId", String.valueOf(paramsMap.get("userId")));
            paramsMap.put("userEname", userSettleNewAccountNo);
            paramsMap.put("createUser", userEname);
            paramsMap.put("createUserName", String.valueOf(paramsMap.get("userCname")));
            String userFundPas = String.valueOf(paramsMap.get("userFundPas"));
            if (StrUtil.isNull(userFundPas)) {
                entity.setMessage("口令不能为空");
                break;
            }
            try {
                paramsMap.put("password", MD5Utils.crypt(userFundPas));
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            paramsMap = toMapDelNull(paramsMap);
            log.info("开通资金账号，请求参数：paramsMap=" + paramsMap);
            //调用RPC
            entity = (ResultEntity) LoadRpcService.service()
                    .doServiceClient("fundsService", "fundsOpenAccount", paramsMap,
                            getInterfaceRegister());
            log.info("处理结果返回：" + entity.getMessage());
            if ("true".equals(entity.getResult()) && null != entity.getEntity() && !"false"
                    .equals(entity.getEntity().toString())) {
                //				request.getSession().setAttribute("openFunds", "T");//标记已经开通钱包功能
                //				request.getSession().setAttribute("loginFus", "T");//标记已经登录

                //修改user表
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("userEname", userEname);
                String cardType = "1";
                String cardNum = userSettleNewAccountNo;
                map.put("cardType", cardType);//卡号类别:1虚拟钱包，2银行卡
                map.put("cardNum", cardNum);//卡号
                ResultEntity entity22 = UctCoreClient.editUserInfo(map);
                //下面这段放开注释，可能冲抵了之前补充的userCname值（首次注册，完善信息，开通钱包后 add xhe 2016-07-13 00:51）
                entity.setResult("true");
                entity.setMessage("开通成功");
                entity.setEntity(entity.getEntity());
            } else {
                entity.setMessage("开通失败");
            }
            break;
        }
        return entity;
    }

    /**
     * 充值，提现
     *
     * @param userEname 资金账号
     * @param amount 金额
     * @param direction 方向
     * @return
     */
    private ResultEntity sendFunds(String userEname, String direction, String amount) {
        ResultEntity entity;
        Map<String, String> prarmMap1 = new HashMap<String, String>();
        prarmMap1.put("userId", userEname);//账号
        prarmMap1.put("amt", amount);//操作金额
        Map<String, Object> fundsMap = new HashMap<String, Object>();
        if ("out".equals(direction)) {
            prarmMap1.put("tradeType", "FOUT");//提现
            List<Map<String, String>> list = new ArrayList<Map<String, String>>();
            list.add(prarmMap1);
            fundsMap.put("funds", list);
            fundsMap.put("remark", "提现");//业务描述
            fundsMap.put("actionId", String.valueOf(new Date().getTime()));//业务流水号
        } else {
            prarmMap1.put("tradeType", "FINT");//充值
            List<Map<String, String>> list = new ArrayList<Map<String, String>>();
            list.add(prarmMap1);
            fundsMap.put("funds", list);
            fundsMap.put("remark", "充值");//业务描述
            fundsMap.put("actionId", String.valueOf(new Date().getTime()));//业务流水号
        }
        //调用RPC
        entity = (ResultEntity) LoadRpcService.service()
                .doServiceClient("fundsService", "fundsPublicOperate", fundsMap,
                        getInterfaceRegister());
        return entity;
    }

    /**
     * 生成最新资金账号
     */
    private String getAccountCreateNo() {
        String startNo = "6228";//账号前缀
//        String strLen = "4";//账号后缀长度
        String accountNo = startNo + "XXXXXX";

//        Map<String, Object> pMap = new HashMap<String, Object>();
//        pMap.put("seqEname", startNo);
//        pMap.put("strLen", strLen);
//        pMap.put("seqMode", "1");
        ResultEntity entity = UctProtoclClient.getInstance().getSeqNextValue(startNo,4,1);
//        ResultEntity entity = (ResultEntity) LoadRpcService.service()
//                .doServiceClient("seqService", "seqNextValue", pMap, getInterfaceRegisterBySeq());
        if ("true".equals(entity.getResult()) && null != entity.getEntity()) {
            accountNo = String.valueOf(entity.getEntity());
        }
        log.info("本次获取的AccountNo = " + accountNo);
        return accountNo;
    }

    /**
     * 若settleAccountNo为空这从登录会话中的资金账号
     */
    private String getAccountNo(HttpServletRequest request, String settleAccountNo) {
        if (StrUtil.isNull(settleAccountNo)) {
            LoginUser loginUser = PortalPubFactory.getInstance().getLoginUser(request);
            String source = request.getParameter("source");//标记入口是，admin后台进入，还是用户中心进入；
            String accountNo = "";
            if ("manager".equals(source)) {
                //管理端
                accountNo = "";
            } else {
                //会员用户端
                accountNo = loginUser.getUser().getCardNum();
                if (StrUtil.isNull(accountNo)) {
                    //只有首次开通钱包+未重新登录就使用作用域里面的（因为开通成功后未更新session里面的loginUser对象）
                    Object obj = request.getSession().getAttribute("fundsUser");
                    if (obj != null) {
                        accountNo = JSONObject.fromObject(obj).getString("userName");
                    }
                }
            }
            return accountNo;
        } else {
            return settleAccountNo;
        }
    }

    /**
     * 进行RPC接口注册的 IP/地址 和 端口的配置定义
     *
     * @return
     */
    private InterfaceRegister getInterfaceRegister() {
        return UctProtoclClient.getInstance()
                .getInterfaceRegister("funds", "funds_server_url", "funds_server_port");
    }

    /**
     * 进行RPC接口序列Seq注册的 IP/地址 和 端口的配置定义
     *
     * @return
     */
    private InterfaceRegister getInterfaceRegisterBySeq() {
        return UctProtoclClient.getInstance()
                .getInterfaceRegister("seq", "info_release_url", "info_release_port");
    }

    public Map<String, Object> toMapDelNull(Map<String, Object> map) {
        Map<String, Object> result = new HashMap<String, Object>();
        for (String key : map.keySet()) {
            if ("class".equals(key))
                continue;
            if (!StrUtil.isNull(String.valueOf(map.get(key))))
                result.put(key, map.get(key));
        }
        return result;
    }

    private String getSqlInStr(String str) {
        String[] strArr = str.split(",");
        String sqlStr = "";
        for (String a : strArr) {
            sqlStr += "'" + a + "',";
        }
        return sqlStr.substring(0, sqlStr.length() - 1);
    }

}
